﻿using CoreCms.Net.Configuration;
using CoreCms.Net.IServices;
using CoreCms.Net.IServices.Pay;
using CoreCms.Net.Model.Entities;
using CoreCms.Net.Model.ViewModels.UI;
using Essensoft.Paylink.WeChatPay.V2.Request;
using Essensoft.Paylink.WeChatPay.V2;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CoreCms.Net.Utility.Extensions;
using CoreCms.Net.Model.ViewModels.DTO;
using CoreCms.Net.Utility.Helper;
using CoreCms.Net.Loging;
using NLog;
using Microsoft.Extensions.DependencyInjection;

namespace CoreCms.Net.Services.Pay
{
    public class PaynowServices : BaseServices<CoreCmsSetting>, IPaynowServices
    {
        private readonly IServiceProvider _serviceProvider;
        private readonly ICoreCmsSettingServices _settingServices;
        public PaynowServices(ICoreCmsSettingServices settingServices, IServiceProvider serviceProvider)
        {
            _settingServices = settingServices;
            _serviceProvider = serviceProvider;
        }


        /// <summary>
        /// 发起支付
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<WebApiCallBack> PubPay(CoreCmsBillPayments entity, CoreCmsPayments cmsPayments)
        {
            var jm = new WebApiCallBack();

            var paynowPayUrl = AppSettingsConstVars.PayCallBackPaynowPayUrl;
            if (string.IsNullOrEmpty(paynowPayUrl))
            {
                jm.msg = "notifyUrl is null";
                return jm;
            }
            NLogUtil.WriteAll(LogLevel.Error, LogType.Order, "notifyUrl", paynowPayUrl);

            //TODO 设置支付货币
            //TODO 设置支付过期时间 
            var allConfigs = await _settingServices.GetConfigDictionaries();
            var time = CommonHelper.GetConfigDictionary(allConfigs, SystemSettingConstVars.OrderCancelTime).ObjectToInt(1);
            if (time > 1) time -= 1;

            PaynowOrder reqOrder = new PaynowOrder()
            {
                mode = "DIRECT",
                orderNo = entity.sourceId,
                subject = entity.payTitle.Length > 50 ? entity.payTitle[..50] : entity.payTitle,
                amount = entity.money.ToString(),
                currencyCode = "SGD",
                notifyUrl = paynowPayUrl,
                transactionOptions = new transactionOptions() { timeout = time * 60 }
            };
            string json = JsonConvert.SerializeObject(reqOrder);
            System.Net.Http.HttpClient client = new System.Net.Http.HttpClient();
            var request = new System.Net.Http.HttpRequestMessage(System.Net.Http.HttpMethod.Post, "https://ipg.fomopay.net/api/orders")
            {
                Content = new System.Net.Http.StringContent(json, Encoding.UTF8, "application/json")
            };
            JObject objRes = JsonConvert.DeserializeObject<JObject>(cmsPayments.parameters);
            string Authorization = CommonHelper.Base64($"{objRes.GetValue("mid").ObjectToString()}:{objRes.GetValue("psk").ObjectToString()}");
            NLogUtil.WriteAll(LogLevel.Error, LogType.Order, "PubPay", json + " " + Authorization);
            request.Headers.Add("Authorization", "Basic " + Authorization);
            // 发送请求并获取响应  
            System.Net.Http.HttpResponseMessage response = await client.SendAsync(request);
            //response.EnsureSuccessStatusCode(); // 确保请求成功  
            if (response.StatusCode == System.Net.HttpStatusCode.OK || response.StatusCode == System.Net.HttpStatusCode.Created)
                jm.status = true;
            // 读取响应内容  
            string responseBody = await response.Content.ReadAsStringAsync();
            JObject resObj = JsonConvert.DeserializeObject<JObject>(responseBody);
            if (resObj.ContainsKey("hint"))
            {
                jm.status = false;
                jm.data = resObj;
                return jm;
            }
            using (var container = _serviceProvider.CreateScope())
            {
                string tranId = resObj.GetValue("primaryTransactionId").ObjectToString(),
                       codeUrl = resObj.GetValue("codeUrl").ObjectToString(),
                       id = resObj.GetValue("id").ObjectToString(),
                       orderNo = resObj.GetValue("orderNo").ObjectToString();
                var billPaymentsServices = container.ServiceProvider.GetService<ICoreCmsBillPaymentsServices>();
                var resultBillPayment = await billPaymentsServices.ToUpdate(entity.paymentId,
                (int)GlobalEnumVars.BillPaymentsStatus.Other, "paynow", entity.money, tranId, codeUrl);


                jm.status = true;
                jm.data = new { id, orderNo, tranId, codeUrl };
            }

            return jm;

        }

        /// <summary>
        /// 用户退款
        /// </summary>
        /// <param name="refundInfo"></param>
        /// <param name="paymentInfo"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public Task<WebApiCallBack> Refund(CoreCmsBillRefund refundInfo, CoreCmsBillPayments paymentInfo)
        {
            throw new NotImplementedException();
        }


        private static string GetTradeType(string tradeType)
        {
            if (tradeType != GlobalEnumVars.PaynowMode.HOSTED.ToString())
                return "DIRECT";
            if (tradeType == GlobalEnumVars.PaynowMode.HOSTED.ToString())
                return "HOSTED";
            return tradeType;
        }
    }
}
